/*
    This file is part of tPortal.

    tPortal is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    tPortal is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with tPortal.  If not, see <http://www.gnu.org/licenses/>.

    The original code was written by Sebastien Bettinger <sebastien.bettinger@gmail.com>

 */

package net.tinyportal.servlet;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.UnavailableException;
import javax.portlet.WindowState;
import javax.portlet.WindowStateException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.tinyportal.Constant;
import net.tinyportal.bean.PortletHolder;
import net.tinyportal.javax.portlet.TpActionRequest;
import net.tinyportal.javax.portlet.TpActionResponse;
import net.tinyportal.javax.portlet.TpPortletConfig;
import net.tinyportal.javax.portlet.TpPortletContext;
import net.tinyportal.javax.portlet.TpPortletPreference;
import net.tinyportal.javax.portlet.TpPortletURL;
import net.tinyportal.javax.portlet.TpRenderRequest;
import net.tinyportal.javax.portlet.TpRenderResponse;
import net.tinyportal.tools.FictiveHttpServletResponse;
import net.tinyportal.tools.ParsePortletXML;
import net.tinyportal.tools.PortletXML;
import net.tinyportal.tools.TpPortletSessionConfig;
import net.tinyportal.tools.ZipUtils;

public class TckServlet extends HttpServlet  {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2259753044074747050L;

	ServletConfig config;
	public void init(ServletConfig config) {
		try {
			super.init(config);
			this.config = config;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		HttpSession session = request.getSession(true);

		ServletContext context = getServletContext();

		/*
		 * Map des portlets passé a la jsp pour l'affichage du portail
		 */
		Map<String, PortletHolder> portletsMap = new HashMap<String, PortletHolder>();

		Map<String, TpPortletContext> portletsContext = new HashMap<String, TpPortletContext>(); 

		String[] portletsNameRequest = request.getParameterValues("portletName");
		if (portletsNameRequest!=null) {
			/*
			 * On va charger les portlets présent dans le répertoire indiqué
			 */

			Portal.resetOnlyPortlet(); // dans le cas du tck, on vide la liste a chaque appel..
			PortletLoader pLoader = new PortletLoader(context);
			for(String portletNameRequest:portletsNameRequest) {

				String portletWar = portletNameRequest.split("/")[0]; // répertoire
				String portletName = null;
				if (portletNameRequest.split("/").length == 2) {
					portletName = portletNameRequest.split("/")[1];// nom du portlet
					Portal.addOnlyPortlet(portletName);
				}

				String portlets_real_Path = context.getRealPath(Constant.portlets_path);
				File portletsPathFile = new File(portlets_real_Path + "/" + portletWar);
				String portlet_directory = portletsPathFile.getAbsolutePath();
				if (!(portletsPathFile.exists() & portletsPathFile.isDirectory())) {
					ZipUtils.unzip(portlet_directory+".war",portlet_directory+"/");
				}

				try {
					/*
					 * Le loader va charger les portlets et alimenter l'objet Portal
					 */
					StringBuffer portlet_path = new StringBuffer(portlet_directory); //.append("/").append(portlet_directory);
					Portal.addPortlets(
							pLoader.load(new File(portlet_path.toString()), portletName)
							);
					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		/*
		 * Affichage
		 * On va parcourir les portlets présent dans l'objet portal
		 * et s'en occuper
		 */
		for(String portletName: Portal.getPortletSet()) {
			/*
			 * Si le portle n'est pas actif, on continue
			 */
			if (!Portal.isActivePortlet(portletName)) continue;

			/*
			 * On récupère le bean associé au portlet
			 */
			PortletHolder bean = Portal.getPortlet(request, portletName);
			GenericPortlet portlet = bean.getPortlet();
			/*
			 * DOGET
			 */


			String portletId = TpPortletURL.getPortletId(bean);

			TpPortletContext TpPortletContext = (TpPortletContext) portlet.getPortletContext();
			TpRenderRequest TPrequest = new TpRenderRequest(bean, request, TpPortletContext);
			TpRenderResponse TPresponse = new TpRenderResponse(response, portletId);

			/*
			 * On positionne le bean portlet dans la requête pour pouvoir y accéder depuis les taglibs
			 */
			TPrequest.setAttribute(Constant.session_portlet_bean,bean);

			bean.setRenderRequest(TPrequest);
			bean.setRenderResponse(TPresponse);
			bean.setPortletConfig(portlet.getPortletConfig());

			try {	

				StringBuffer sb = new StringBuffer(portletId).append("_").append("action");
				String action = request.getParameter(sb.toString());
				if ("action".equalsIgnoreCase(action)) {

					Portal.doAction(request, response, bean, portlet);
				} else if ("render".equalsIgnoreCase(action)) {
					Portal.doRender(request, response, bean, portlet);
				} else {
					sb = new StringBuffer(portletId).append("_").append("mode");
					String mode = request.getParameter(sb.toString());
					if (null != mode) {
						bean.setPortletMode(new PortletMode(mode));
					}
					sb = new StringBuffer(portletId).append("_").append("state");
					String state = request.getParameter(sb.toString());
					if (null != state) {
						bean.setWindowState(new WindowState(state));
					}
				}
				Portal.doRender(request, response, bean, portlet);
				Portal.doRefresh(request, response, bean, portlet);
				portletsMap.put(bean.getPortletName(), bean);
			} catch (UnavailableException ue) {
				portlet.destroy();
				Portal.addDisabledPortlet(portletName);

			} catch (Exception e) {
				e.printStackTrace();
				bean.setTitle("Erreur sur le portlet");
				bean.setContent("/!\\ Erreur !!" + e.getMessage());
				portletsMap.put(bean.getPortletName(), bean);
			}
			//						portletsBean.add(portletBean);
		}
		/*
		 * On fait le rendu du portail
		 */
		RequestDispatcher servletDispatcher;

		request.setAttribute(Constant.session_portlet_bean_map, portletsMap);
		//						request.setAttribute(Constant.session_portlet_bean_list, portletsBean);
		response.setHeader("Content-Type", "text/html");
		servletDispatcher = context.getRequestDispatcher("/WEB-INF/jsp/tck.jsp");
		servletDispatcher.include(request, response);



	} 



	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}


}
